package com.reader.api.exception;

import com.reader.core.entity.ResultMessageInfo;
import com.reader.core.exception.CustomException;
import com.reader.core.utils.FastJsonUtil;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authz.AuthorizationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.http.HttpServletRequest;

/**
 *  * 通用异常处理
 * @author jiahaikun
 * @date 2018-07-26
 */
@RestControllerAdvice
public class GlobalExceptionHandler {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    protected HttpServletRequest request;

    /**
     * 拦截处理所有用户自定义异常
     *
     * @param req
     * @param e
     * @return
     * @throws Exception
     */
    @ExceptionHandler(value = CustomException.class)
    @ResponseBody
    public ResultMessageInfo customErrorHandler(HttpServletRequest req, CustomException e) throws Exception {
        ResultMessageInfo r = new ResultMessageInfo();
        r.setCode(e.getCode());
        r.setData(e.getData());
        r.setMsg(e.getMsg());
        r.setUrl(req.getRequestURL().toString());
        logger.error("用户自定义异常详细信息："+FastJsonUtil.toJSONString(r));//写入日志
        return r;
    }

    /**
     * 拦截处理shiro访问权限异常
     * @param req 可获取url
     * @param e
     * @return
     * @throws Exception
     */
    @ExceptionHandler(AuthorizationException.class)
    public ResultMessageInfo handleAuthorizationException(HttpServletRequest req, AuthorizationException e){
        ResultMessageInfo r = new ResultMessageInfo();
        r.setCode(ResultMessageInfo.State.UNAUTHORIZED.getCode());
        r.setUrl(req.getRequestURL().toString());
        r.setMsg("您没有访问权限，请联系管理员授权!");
        logger.error("AuthorizationException:::"  + FastJsonUtil.toJSONString(r) +":::"+e.getMessage());//写入日志
        return  r;
    }

   /**
     * 权鉴验证
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(AuthenticationException.class)
    public ResultMessageInfo handleAuthenticationException(HttpServletRequest req, AuthenticationException e){
        ResultMessageInfo r = new ResultMessageInfo();
        r.setCode(ResultMessageInfo.State.FAILED.getCode());
        r.setUrl(req.getRequestURL().toString());
        r.setMsg(e.getMessage());
        logger.error("AuthenticationException:::"  + FastJsonUtil.toJSONString(r) +":::"+e.getMessage());//写入日志
        return  r;
    }

    /**
     * 拦截处理所有未知异常
     *
     * @param req 可获取url
     * @param e
     * @return
     * @throws Exception
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ResultMessageInfo errorHandler(HttpServletRequest req, Exception e) throws Exception {
        ResultMessageInfo r = new ResultMessageInfo();
        r.setCode(ResultMessageInfo.State.ERROR.getCode());
        r.setUrl(req.getRequestURL().toString());
        r.setMsg(ResultMessageInfo.State.ERROR.getMessage());
        logger.error("Exception:::" + FastJsonUtil.toJSONString(r));//写入日志
        logger.error("ExceptionStack:::"+getStackMsg(e));

        return r;
    }

    /**
     * 异常堆栈信息转化为String
     * @param e
     * @return
     */
    private String getStackMsg(Exception e) {

        StringBuffer sb = new StringBuffer();
        StackTraceElement[] stackArray = e.getStackTrace();
        for (int i = 0; i < stackArray.length; i++) {
            StackTraceElement element = stackArray[i];
            sb.append(element.toString() + "\n");
        }
        return sb.toString();
    }



}

